package com.example.huadu_server.user.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.example.huadu_server.appointment.dto.AppointmentDTO;
import com.example.huadu_server.appointment.dto.ChangeDateDTO;
import com.example.huadu_server.appointment.service.AppointmentService;
import com.example.huadu_server.config.Response;
import com.example.huadu_server.house.entity.House;
import com.example.huadu_server.house.service.HouseService;
import com.example.huadu_server.landlord.entity.LandlordSchedule;
import com.example.huadu_server.landlord.service.LandlordScheduleService;
import com.example.huadu_server.user.dto.ForgetPasswordDTO;
import com.example.huadu_server.user.dto.ModifyPasswordDTO;
import com.example.huadu_server.user.dto.UpdateInfoDTO;
import com.example.huadu_server.user.dto.UserInfoDTO;
import com.example.huadu_server.user.entity.User;
import com.example.huadu_server.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private LandlordScheduleService landlordScheduleService;
    /**
     * 修改密码
     */
    @PostMapping("/modifyPass")
    public Response<String> modifyPassword(@RequestBody @Valid ModifyPasswordDTO modifyPasswordDTO) {
        int userId = StpUtil.getLoginIdAsInt();
        return userService.modifyPassword(
                userId,
                modifyPasswordDTO.getOldPassword(),
                modifyPasswordDTO.getNewPassword(),
                modifyPasswordDTO.getConfirmPassword()
        );
    }

    /**
     * 获取验证码 (GET)
     */
    @GetMapping("/forgetPassCode")
    public Response<String> sendForgetPasswordCode(@RequestParam String email) {
        return userService.sendForgetPasswordCode(email);
    }

    /**
     * 重置密码 (POST)
     */
    @PostMapping("/forgetPass")
    public Response<String> resetPassword(@RequestBody @Valid ForgetPasswordDTO forgetPasswordDTO) {
        return userService.resetPassword(
                forgetPasswordDTO.getEmail(),
                forgetPasswordDTO.getCode(),
                forgetPasswordDTO.getNewPassword(),
                forgetPasswordDTO.getConfirmPassword()
        );
    }

    /**
     * 获取用户个人信息
     *
     * @return ResponseEntity<Response < User>>
     */
    @GetMapping("/userInfo")
    public ResponseEntity<Response<User>> getUserInfo() {
        // 获取当前登录用户的 ID
        int userId = StpUtil.getLoginIdAsInt();

        // 调用 Service 层获取用户信息
        Response<User> response = userService.getUserInfoById(userId);

        return ResponseEntity.status(response.getCode()).body(response);
    }


    /**
     * 修改用户个人信息
     */
    @PostMapping("/updateInfo")
    public Response<String> updateUserInfo(@RequestBody @Valid UpdateInfoDTO updateInfoDTO) {
        int userId = StpUtil.getLoginIdAsInt(); // 获取当前登录用户的 ID
        return userService.updateUserInfo(userId, updateInfoDTO);
    }

    /**
     * 获取修改邮箱验证码
     */
    @GetMapping("/getUpdateEmailCode")
    public Response<String> sendUpdateEmailCode(@RequestParam String email) {
        return userService.sendUpdateEmailCode(email);
    }

    /**
     * 修改用户邮箱
     */
    @PostMapping("/updateEmail")
    public Response<String> updateUserEmail(@RequestBody @Valid UserInfoDTO userInfoDTO) {
        int userId = StpUtil.getLoginIdAsInt(); // 获取当前登录用户的 ID
        return userService.updateUserEmail(userId, userInfoDTO);
    }

    /**
     * 上传用户头像
     */
    @PostMapping("/uploadLogo")
    public Response<String> uploadUserLogo(@RequestParam("file") MultipartFile file) {
        int userId = StpUtil.getLoginIdAsInt(); // 获取当前登录用户 ID

        // 检查是否上传文件---哪怕没有上传图片也会有默认值，所以先排除掉默认值再进行判断是否上传文件
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null || originalFilename.isEmpty() ||
                originalFilename.startsWith("1735872250277_")) {
            return new Response<>(400, "请上传图片", null);
        }
        return userService.uploadUserLogo(file, userId);
    }

    @Autowired
    private HouseService houseService;

    /**
     * 分页查询房源信息
     *
     * @param pageNo   当前页码
     * @param pageSize 每页记录数
     * @return 分页查询结果
     */
    @GetMapping("/list/{pageNo}/{pageSize}")
    public ResponseEntity<Response<Map<String, Object>>> getHousesByPage(
            @PathVariable("pageNo") int pageNo,
            @PathVariable("pageSize") int pageSize) {

        Response<Map<String, Object>> result = houseService.getHousesByPage(pageNo, pageSize);
        return ResponseEntity.status(result.getCode()).body(result);
    }


    /**
     * 房源搜索接口
     *
     * @param searchParams 前端输入的搜索关键词
     * @return 符合条件的房源列表
     */
    @PostMapping("/searchHouse/{pageNo}/{pageSize}")
    public ResponseEntity<Response<Map<String, Object>>> searchHouses(
            @PathVariable("pageNo") int pageNo,
            @PathVariable("pageSize") int pageSize,
            @RequestBody Map<String, Object> searchParams) {

        String keyword = (String) searchParams.get("keyword");
        if (keyword != null && keyword.trim().isEmpty()) {
            keyword = null; // 将空字符串转换为 null
        }
        // 调用 Service 层进行搜索
        Response<Map<String, Object>> result = houseService.searchHouses(keyword, pageNo, pageSize);

        return ResponseEntity.ok(result);
    }

    /**
     * 搜索房源并筛选
     *
     * @param filters 筛选条件
     * @return 符合条件的房源列表
     */
    @PostMapping("/filterHouse/{pageNo}/{pageSize}")
    public ResponseEntity<Response<Map<String, Object>>> filterHouses(
            @PathVariable("pageNo") int pageNo,
            @PathVariable("pageSize") int pageSize,
            @RequestBody(required = false) Map<String, Object> filters) { // 筛选条件
        Response<Map<String, Object>> result = houseService.filterHouses(filters, pageNo, pageSize);
        return ResponseEntity.status(result.getCode()).body(result);
    }

    /**
     * 搜索房源并筛选关键词
     *
     * @param pageNo
     * @param pageSize
     * @param conditions
     * @return
     */
    @PostMapping("/filterHouseByKey/{pageNo}/{pageSize}")
    public ResponseEntity<Response<Map<String, Object>>> filterHousesByKey(
            @PathVariable("pageNo") int pageNo,
            @PathVariable("pageSize") int pageSize,
            @RequestBody Map<String, Object> conditions) {
        // 调用服务层方法
        Response<Map<String, Object>> result = houseService.filterHousesByKey(conditions, pageNo, pageSize);
        return ResponseEntity.status(result.getCode()).body(result);
    }

    /**
     * 通过房源 ID 查询房源详细信息
     *
     * @param houseId 房源 ID
     * @return 房源详细信息
     */
    @GetMapping("/getHouseById/{houseId}")
    public ResponseEntity<Response<House>> getHouseById(@PathVariable("houseId") int houseId, @RequestParam("userId") int userId) {
        Response<House> result = houseService.getHouseById(houseId,userId);
        return ResponseEntity.status(result.getCode()).body(result);
    }

    @Autowired
    private AppointmentService appointmentService;

    /**
     * 预约房源接口
     * 请求头中需要携带 token 参数，接口内部通过 satoken 获取当前登录用户ID并设置到 AppointmentDTO 中
     */
    @PostMapping("/reserveHouse")
    public Response<String> reserveHouse(@RequestBody AppointmentDTO appointmentDTO) {
        // 校验登录状态
        StpUtil.checkLogin();
        // 获取当前登录用户ID，并设置到预约 DTO 中
        int userId = StpUtil.getLoginIdAsInt();
        appointmentDTO.setUserId(userId);
        return appointmentService.reserveHouse(appointmentDTO);
    }



    /**
     * 获取用户预约记录接口
     * 请求头中需要携带 satoken 参数，同时校验请求中的 userId 与当前登录用户是否一致
     */
    @GetMapping("/myAppointments/{pageNo}/{pageSize}")
    public ResponseEntity<Response<Map<String, Object>>> getAppointmentsByUserId(
            @PathVariable int pageNo,
            @PathVariable int pageSize) {
        // 校验登录状态
        StpUtil.checkLogin();
        int currentUserId = StpUtil.getLoginIdAsInt();
        Response<Map<String, Object>> result = appointmentService.getAppointmentsByUserId(currentUserId, pageNo, pageSize);
        return ResponseEntity.status(result.getCode()).body(result);
    }

    /**
     * 变更预约时间接口
     * appointmentId 通过路径传参，新时间从请求体中获取，时间格式为 "yyyy-MM-dd HH:mm"
     */
    @PostMapping("/changeTime")
    public ResponseEntity<Response<String>> changeAppointmentTime(
            @RequestBody ChangeDateDTO changeDateDTO) {
        // 使用 satoken 校验登录状态
        StpUtil.checkLogin();

        // 通过 satoken 获取当前登录用户的 ID
        int userId = StpUtil.getLoginIdAsInt();

        // 调用 service 层的变更预约时间方法
        Response<String> result = appointmentService.changeAppointmentTime(changeDateDTO);

        // 返回响应
        return ResponseEntity.status(result.getCode()).body(result);
    }

    /**
     * 取消预约接口
     * 请求头中需要携带 token 参数，接口内部通过 satoken 获取当前登录用户ID并设置到 AppointmentDTO 中
     */
    @PostMapping("/cancelAppointment/{id}")
    public Response<String> cancelAppointment(@PathVariable("id") Long appointmentId) {
        // 校验登录状态
        StpUtil.checkLogin();
        // 获取当前登录用户ID，并设置到预约 DTO 中
        int userId = StpUtil.getLoginIdAsInt();
        return appointmentService.cancelAppointment(appointmentId, userId);

    }

    /**
     * 收藏房源接口
     * 请求头中需携带 satoken 参数
     */
    @PostMapping("/addFavorite/{houseId}")
    public ResponseEntity<Response<String>> addFavorite(@PathVariable("houseId") int houseId) {
        // 使用 satoken 校验登录状态
        StpUtil.checkLogin();
        // 通过 satoken 获取当前登录用户的 ID
        int userId = StpUtil.getLoginIdAsInt();
        Response<String> result = houseService.addFavorite(houseId, userId);
        return ResponseEntity.status(result.getCode()).body(result);
    }

    /**
     * 取消收藏房源接口
     * @param houseId
     * @return
     */
    @DeleteMapping("/removeFavorite/{houseId}")
    public ResponseEntity<Response<String>> removeFavorite(@PathVariable("houseId") int houseId) {
        // 使用 satoken 校验登录状态
        StpUtil.checkLogin();
        // 通过 satoken 获取当前登录用户的 ID
        int userId = StpUtil.getLoginIdAsInt();
        Response<String> result = houseService.removeFavorite(houseId, userId);
        return ResponseEntity.status(result.getCode()).body(result);
    }

    /**
     * 猜你喜欢推荐接口
     * 请求头中需携带 token，推荐结果基于用户在预约、浏览和消息中的行为数据计算
     * 新的URL示例：GET /user/recommendedHouses/1/10
     */
    @GetMapping("/recommendedHouses/{pageNo}/{pageSize}")
    public ResponseEntity<Response<Map<String, Object>>> getRecommendedHouses(
            @PathVariable int pageNo,
            @PathVariable int pageSize) {
        // 校验登录状态
        StpUtil.checkLogin();
        int userId = StpUtil.getLoginIdAsInt();
        Response<Map<String, Object>> result = houseService.getRecommendedHouses(userId, pageNo, pageSize);
        return ResponseEntity.status(result.getCode()).body(result);
    }

    /**
     * 获取用户收藏的房源列表
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("/myFavorites/{pageNo}/{pageSize}")
    public ResponseEntity<Response<Map<String, Object>>> getFavoriteHouses(
            @PathVariable("pageNo") int pageNo,
            @PathVariable("pageSize") int pageSize) {
        // 通过 satoken 校验登录状态
        StpUtil.checkLogin();
        int userId = StpUtil.getLoginIdAsInt();
        Response<Map<String, Object>> result = houseService.getFavoriteHouses(userId, pageNo, pageSize);
        return ResponseEntity.status(result.getCode()).body(result);
    }


    /**
     * 用户获取指定房东未来七天的档期记录
     * @param landlordId 房东ID（路径传参）
     * @return 返回房东未来七天的档期数据
     */
    @GetMapping("/landlordSchedules/{landlordId}")
    public ResponseEntity<Response<List<LandlordSchedule>>> getLandlordSchedulesForUser(@PathVariable int landlordId) {
        StpUtil.checkLogin();

        // 1. 获取今天（含）到第 7 天
        Calendar calStart = Calendar.getInstance();
        calStart.add(Calendar.DAY_OF_MONTH, 0); // +0 表示从“今天”开始
        Date startDate = calStart.getTime();

        calStart.add(Calendar.DAY_OF_MONTH, 7); // 再加 7 天 => 共有 7 天
        Date endDate = calStart.getTime();

        // 2. 调用服务
        List<LandlordSchedule> schedules = landlordScheduleService.getSchedulesForLandlord(landlordId, startDate, endDate);

        // 3. 返回
        return ResponseEntity.ok(new Response<>(200, "查询成功", schedules));
    }



}
